package cn.turboinfo.dongying.api.gateway.admin.controller.policy;

import cn.turboinfo.dongying.api.domain.admin.usecase.policy.CreatePolicyUseCase;
import cn.turboinfo.dongying.api.domain.admin.usecase.policy.ListAllPolicyUseCase;
import cn.turboinfo.dongying.api.domain.admin.usecase.policy.ListPolicyUseCase;
import cn.turboinfo.dongying.api.domain.admin.usecase.policy.UpdatePolicyUseCase;
import cn.turboinfo.dongying.api.entity.admin.fo.policy.PolicyCreateFO;
import cn.turboinfo.dongying.api.entity.admin.fo.policy.PolicySearchFO;
import cn.turboinfo.dongying.api.entity.admin.fo.policy.PolicyUpdateFO;
import cn.turboinfo.dongying.api.entity.common.enumeration.policy.PolicyType;
import cn.turboinfo.dongying.api.entity.common.pojo.policy.Policy;
import cn.turboinfo.dongying.api.entity.common.pojo.policy.QPolicy;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.ResponseBodyWrapper;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.CollectionDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.SortFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.ResponseBodyWrapper;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.CollectionDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.SortFO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.request.QSort;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanSearchHelper;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Slf4j
@RequiredArgsConstructor
@Controller
@ResponseBodyWrapper
@RequestMapping(value = "/admin/policy")
public class PolicyController {

    private final ListPolicyUseCase listPolicyUseCase;

    private final ListAllPolicyUseCase listAllPolicyUseCase;

    private final CreatePolicyUseCase createPolicyUseCase;

    private final UpdatePolicyUseCase updatePolicyUseCase;

    @RequiresPermissions("policy:list")
    @GetMapping("/list")
    public LimitDataFO<Policy> list(@Valid PolicySearchFO search, LimitFO page, SortFO sort) {
        QRequest request = QBeanSearchHelper.convertQRequest(search);

        if (sort.getSortFields() == null) {
            sort.setSortFields(new String[]{QPolicy.id + "|" + QSort.Order.DESC.name()});
        }

        ListPolicyUseCase.OutputData outputData = listPolicyUseCase.execute(ListPolicyUseCase.InputData
                .builder()
                .request(request)
                .requestPage(page.toQPage(sort.toQSortList()))
                .build());

        return LimitDataFO.fromQResponse(outputData.getPageResponse());
    }

    @RequiresPermissions("policy:list")
    @GetMapping("/listAll")
    public CollectionDataFO<Policy> listAll(@RequestParam(required = false) PolicyType policyType) {

        ListAllPolicyUseCase.OutputData outputData = listAllPolicyUseCase.execute(ListAllPolicyUseCase.InputData
                .builder()
                .policyType(policyType)
                .build());

        return CollectionDataFO.<Policy>builder().items(outputData.getPolicyList()).build();
    }

    @RequiresPermissions("policy:create")
    @PostMapping("/create")
    public void create(@RequestBody @Valid PolicyCreateFO fo) {
        createPolicyUseCase.execute(CreatePolicyUseCase.InputData
                .builder()
                .createFO(fo)
                .build());
    }

    @RequiresPermissions("policy:update")
    @PostMapping("/update")
    public void update(@RequestBody @Valid PolicyUpdateFO fo) {
        updatePolicyUseCase.execute(UpdatePolicyUseCase.InputData
                .builder()
                .updateFO(fo)
                .build());
    }

}
